package com.authine.cloudpivot.ext.controller;

import com.alibaba.fastjson.JSONObject;
import com.authine.cloudpivot.engine.api.model.organization.UserModel;
import com.authine.cloudpivot.engine.api.model.runtime.BizObjectCreatedModel;
import com.authine.cloudpivot.engine.api.model.runtime.WorkItemModel;
import com.authine.cloudpivot.engine.api.model.runtime.WorkflowInstanceModel;
import com.authine.cloudpivot.engine.enums.status.SequenceStatus;
import com.authine.cloudpivot.ext.Utils.CustomSchemaCode;
import com.authine.cloudpivot.ext.service.CloudSqlService;
import com.authine.cloudpivot.web.api.controller.base.BaseController;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 油卡信息记录
 */
@Slf4j
@RestController
@RequestMapping("/public/OilCarInformationRecordController")
public class OilCarInformationRecordController extends BaseController {

    @Autowired
    private AttributeController attributeController;

    @Autowired
    CloudSqlService sqlService;

    /**
     * 油卡信息记录  审批流完成后 数据写到-油卡信息记录 基础表，补全基础表的数据
     */
    @RequestMapping("finish")
    public void finish(String bizId) {

        BizObjectCreatedModel bizObject = getBizObjectFacade().getBizObject(CustomSchemaCode.oilCarInformationRecord, bizId);
        List<Map<String, Object>> list = (List<Map<String, Object>>) bizObject.get(CustomSchemaCode.oilCarInformationRecordDetai);
        String now = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        String approval = getFileBaseInfoWorkFlowApproval(bizObject);
        for (Map<String, Object> map : list) {

            try {
                Map<String, Object> data = fileInfoBaseMap(map, now, approval);
                //将子表中数据处理，随后更新至【油卡信息记录 基础表】，需要判断是否存在
                String id = existsBizObject(map);
                if (StringUtils.isNotBlank(id)) {
                    data.put("id", id);
                }

                BizObjectCreatedModel model = new BizObjectCreatedModel(CustomSchemaCode.oilCarInformationBasic, data, false);
                model.setSequenceStatus(SequenceStatus.COMPLETED.name());
                log.info("油卡信息记录将要更新到基础表的数据：\n{}", JSONObject.toJSONString(model));
                id = getBizObjectFacade().saveBizObject(CustomSchemaCode.adminUserId, model, false);
                log.info("油卡信息记录-新增成功");
                //调用存储过程
                callProcess(id);

            } catch (Exception e) {
                log.info("油卡信息记录-操作失败");
                log.info(e.getMessage(), e);
            }

        }
    }

    @RequestMapping("toVoid")
    public void toVoid(String bizId) {
        BizObjectCreatedModel bizObject = getBizObjectFacade().getBizObject(CustomSchemaCode.toVoidOilCarInformation, bizId);
        List<Map<String, Object>> list = (List<Map<String, Object>>) bizObject.get(CustomSchemaCode.toVoidOilCarInformationDetai);
        String now = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        //获取审批人
        String approval = getFileBaseInfoWorkFlowApproval(bizObject);
        for (Map<String, Object> map : list) {
            try {
                String id = existsBizObject(map);
                //判断是否已存在，如果不存在，放弃这条数据，直接跳过此次循环
                if (StringUtils.isBlank(id)) {
                    continue;
                }

                //获取数据
                Map<String, Object> data = fileInfoBaseMap(map, now, approval);
                data.put("id", id);

                BizObjectCreatedModel model = new BizObjectCreatedModel(CustomSchemaCode.oilCarInformationBasic, data, false);
                model.setSequenceStatus(SequenceStatus.CANCELED.name());
                id = getBizObjectFacade().saveBizObject(CustomSchemaCode.adminUserId, model, false);
                log.info("场地信息基础表  作废操作成功 ");
                //调用存储过程
                callProcessToVoid(id);

            } catch (Exception e) {
                log.info("场地信息基础表-操作失败");
                log.info(e.getMessage(), e);
            }

        }
    }

    /**
     * 查询审批人,返回  员工号+姓名
     *
     * @param bizObject
     * @return
     */
    private String getFileBaseInfoWorkFlowApproval(BizObjectCreatedModel bizObject) {
        WorkflowInstanceModel instanceModel = getWorkflowInstanceFacade().getByObjectId(bizObject.getId());
        List<WorkItemModel> workItems = getWorkflowInstanceFacade().getWorkItems(instanceModel.getId(), true);
        final String finalActivityCode = "Activity22";
        Optional<WorkItemModel> first = workItems.stream().filter(a -> a.getActivityCode().equals(finalActivityCode)).findFirst();
        String participant = null;
        if (first.isPresent()) {
            WorkItemModel workItemModel = first.get();
            participant = workItemModel.getParticipant();
        }

        if (participant == null) {
            final String finalActivityCode2 = "Activity18";
            Optional<WorkItemModel> second = workItems.stream().filter(a -> a.getActivityCode().equals(finalActivityCode2)).findFirst();
            if (second.isPresent()) {
                WorkItemModel workItemModel = second.get();
                participant = workItemModel.getParticipant();
            }
        }


        if (participant == null) {
            participant = bizObject.getCreater().getId();
        }

        UserModel user = getOrganizationFacade().getUser(participant);


        return new StringBuilder(user.getEmployeeNo()).append("　").append(user.getName()).toString();
    }


    /**
     * 判断是否已存在
     *
     * @return
     */
    private String existsBizObject(Map data) {

        //卡号
        String cardNumber = (String) data.get("cardNumber");

        String tableName = getBizObjectFacade().getTableName(CustomSchemaCode.oilCarInformationBasic);

        StringBuilder sql = new StringBuilder("select id  from ").append(tableName).append(" where cardNumber ='").append(cardNumber).append("'");

        Map<String, Object> map = sqlService.getMap(sql.toString());

        return (String) map.get("id");
    }

    /**
     * 转换成  待完成工作清单 基础表 的数据
     *
     * @param map
     * @param auditDate
     * @return
     */
    private Map<String, Object> fileInfoBaseMap(Map<String, Object> map, String auditDate, String approval) {
        Map<String, Object> data = new HashMap<>();
        data.put("company", map.get("company"));
        data.put("companyNumber", map.get("companyNumber"));
        data.put("adminDeptFid", map.get("adminDeptFid"));
        data.put("adminDeptFNumber", map.get("adminDeptFNumber"));
        data.put("adminDeptName", map.get("adminDeptName"));
        data.put("cardNumber", map.get("cardNumber"));
        data.put("attribute", map.get("attribute"));
        data.put("enabledTime", map.get("enabledTime"));
        data.put("closingTime", map.get("closingTime"));
        data.put("useStatus", map.get("useStatus"));
        data.put("managementDeptFid", map.get("managementDeptFid"));
        data.put("managementDeptFNumber", map.get("managementDeptFNumber"));
        data.put("managementDeptName", map.get("managementDeptName"));
        data.put("relevancePostA", map.get("relevancePostA"));
        data.put("postANumber", map.get("postANumber"));
        data.put("postAName", map.get("postAName"));
        data.put("relevancePostB", map.get("relevancePostB"));
        data.put("postBNumber", map.get("postBNumber"));
        data.put("postBName", map.get("postBName"));
        data.put("description", map.get("description"));
        //审批人
        data.put("approval", approval);
        //审批时间
        data.put("auditDate", auditDate);
        return data;
    }

    /**
     * ----油卡信息记录
     * exec   SyncCardInfo
     *
     * @comid nvarchar(100),            ----公司id
     * @cardnum nvarchar(100),            ----卡号  100 011 320 003 688 6001 中间带空格，仅去除首尾空格?
     * @Property nvarchar(100),            ----属性
     * @InDate datetime,                ----启用时间
     * @OutDate datetime,                ----封闭时间
     * @In nvarchar(10),            ----在用		1 √    0  ×
     * @deptid nvarchar(100),            ----管理部门ID
     * @PositionA nvarchar(50),            ----岗A代码
     * @PositionB nvarchar(50),            ----岗B代码
     * @WorkDesc nvarchar(200),            ----工作说明
     * @auditor nvarchar(100)            ----审批人   02.0100 张三
     */
    private void callProcess(String bizId) {

        if (StringUtils.isEmpty(bizId)) {
            return;
        }
        //编写sql
        String tableName = getBizObjectFacade().getTableName(CustomSchemaCode.oilCarInformationBasic);
        StringBuilder sql = new StringBuilder("SELECT * from ")
                .append(tableName).append(" where id ='")
                .append(bizId).append("';");
        //查询到入参
        Map<String, Object> map = sqlService.getMap(sql.toString());

        log.info("根据表单Id查询到的油卡信息基础表数据:\n{}", JSONObject.toJSONString(map));

        //调用存储过程
        String company = MapUtils.getString(map, "company", "");
        String cardNumber = MapUtils.getString(map, "cardNumber", "");
        String attribute = MapUtils.getString(map, "attribute", "");

//        Date enabledTimeTemp = (Date) map.get("enabledTime");
//        String enabledTime = enabledTimeTemp == null ? "" : DateFormatUtils.format(enabledTimeTemp, "yyyy-MM-dd");
        LocalDateTime enabledTimeTemp = (LocalDateTime) map.get("enabledTime");
        String enabledTime =  ObjectUtils.isEmpty(enabledTimeTemp) ? "" : enabledTimeTemp.toLocalDate().toString();

//        Date closingTimeTemp = (Date) map.get("closingTime");
//        String closingTime = closingTimeTemp == null ? "" : DateFormatUtils.format(closingTimeTemp, "yyyy-MM-dd");
        LocalDateTime closingTimeTemp = (LocalDateTime) map.get("closingTime");
        String closingTime =  ObjectUtils.isEmpty(closingTimeTemp) ? "" : closingTimeTemp.toLocalDate().toString();

        String useStatus = MapUtils.getString(map, "useStatus", "");
        useStatus = "√".equals(useStatus) ? "1" : "0";

        String managementDeptFid = MapUtils.getString(map, "managementDeptFid", "");
        String postANumber = MapUtils.getString(map, "postANumber", "");
        String postBNumber = MapUtils.getString(map, "postBNumber", "");
        String description = MapUtils.getString(map, "description", "");
        String approval = MapUtils.getString(map, "approval", "");

        String execSql = String.format("exec [HG_LINK].[hg].[dbo].SyncCardInfo '%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s'",
                company, cardNumber, attribute, enabledTime, closingTime, useStatus,
                managementDeptFid, postANumber, postBNumber, description, approval);
        log.info("\n==========准备调用[油卡信息记录]存储过程:{}", execSql);
        sqlService.execute(CloudSqlService.htEas, execSql);
        log.info("\n=============[油卡信息记录]存储过程执行完成");
    }

    /**
     * ----油卡信息记录 作废
     * exec  CardInfoDisable
     *
     * @cardnum nvarchar(100)            ----卡号  100 011 320 003 688 6001 中间带空格，仅去除首尾空格
     */
    private void callProcessToVoid(String bizId) {

        if (StringUtils.isEmpty(bizId)) {
            return;
        }
        //编写sql
        String tableName = getBizObjectFacade().getTableName(CustomSchemaCode.oilCarInformationBasic);
        StringBuilder sql = new StringBuilder("SELECT * from ")
                .append(tableName).append(" where id ='")
                .append(bizId).append("';");
        //查询到入参
        Map<String, Object> map = sqlService.getMap(sql.toString());
        log.info("根据表单Id查询到的油卡信息基础表数据:\n{}", JSONObject.toJSONString(map));

        //准备调用存储过程的入参
        String cardNumber = MapUtils.getString(map, "cardNumber", "");
        String execSql = String.format("exec [HG_LINK].[hg].[dbo].CardInfoDisable '%s'", cardNumber);
        log.info("\n==========准备调用[油卡信息记录 作废]存储过程:{}", execSql);
        sqlService.execute(CloudSqlService.htEas, execSql);
        log.info("\n=============[油卡信息记录 作废]存储过程执行完成");

    }

}
